home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / mpwtools.cpt / misc src / mcompress.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-24  |  6.0 KB  |  209 lines

  1. /* Copyright 1988, Gail Zacharias.  All rights reserved.
  2.  * Permission is hereby granted to copy, reproduce, redistribute or
  3.  * otherwise use this software provided there is no monetary profit
  4.  * gained specifically from its use or reproduction, it is not sold,
  5.  * rented, traded or otherwise marketed, and this copyright notice 
  6.  * and the software version number is included prominently in any copy
  7.  * made.
  8.  * This is mcompress version 1.0.
  9.  *
  10.  * Send comments, suggestions, bug reports (not bloody likely), feature
  11.  * requests, etc. to gz@entity.com.
  12.  *
  13.  */
  14.  
  15. /* This program demonstrates the use of the compstream library.  It
  16.    implements a simple unix-compatible compress/decompress MPW tool.
  17.    It only handles data forks of files for now.
  18.  */
  19.  
  20. #include <stdio.h>
  21. #ifdef     macintosh
  22. #include <Types.h>
  23. #include <Files.h>
  24. #include <CursorCtl.h>
  25. #endif     macintosh
  26.  
  27. extern long compinit(), uncompinit();
  28. extern int compwrite(), uncompread(), compclose(), uncompclose();
  29.  
  30. stdwrite (stream, size, buf)
  31.   FILE *stream;
  32.   char *buf;
  33. {
  34.   return (size == fwrite(buf, 1, size, stream)) ? 0 : -1;
  35. }
  36.  
  37. stdread (stream, size, buf)
  38.   FILE *stream;
  39.   char *buf;
  40. {
  41.   return fread(buf, 1, size, stream);
  42. }
  43.  
  44. main (argc, argv)
  45.   char **argv;
  46. {
  47.   int block_compress = 1, nbits = 0, header = 1;
  48.   int decomp = 0;
  49.   int unix = 0;
  50.   int i;
  51.   FILE *inf, *outf;
  52.   char buf[512];
  53.   long cstream;
  54.   int n;
  55.  
  56. #ifdef    macintosh
  57.     InitCursorCtl(nil);
  58. #endif    macintosh
  59.  
  60.   while (--argc > 0 && **++argv == '-') {
  61.     char *argp = &argv[0][1];
  62.     if (!*argp) break;
  63.     do switch (*argp++) {
  64.       case 'd': decomp = 1; break;
  65.       case 'C': block_compress = 0; break;
  66.       case 'n': header = 0; break;
  67.       case 'b': if (*argp == '\0') {
  68.                   if (--argc == 0) goto badarg;
  69.           argp = *++argv;
  70.         }
  71.         nbits = 0;
  72.         while ('0' <= *argp && *argp <= '9')
  73.           nbits = nbits*10 + (*argp++ - '0');
  74.         if (*argp || nbits < 9 || nbits > 16) goto badarg;
  75.         break;
  76.       case 'u':    unix = 1;    /* do CR<->LF for Unix text files */
  77.         break;
  78.       /* case 'm': macbinary = 1; break; /* not yet */
  79.       default: goto badarg;
  80.     } while (*argp);
  81.   }
  82.   if (decomp && (!nbits && !header || nbits && header)) goto badarg;
  83.   if (argc > 2) goto badarg;
  84.   if (!nbits) nbits = 16;
  85.   inf = stdin; outf = stdout;
  86.   if (argc > 0 && strcmp("-", argv[0])) {
  87.     if (!(inf = fopen(argv[0], "r"))) {
  88.       fprintf(stderr, "mcompress: can't open \"%s\" for reading\n", argv[0]);
  89.       return 1;
  90.     }
  91.     if (!decomp && argc == 1) {
  92.       strcpy(buf, argv[0]);
  93.       strcat(buf, ".Z");
  94.       if (outf = fopen(buf, "r")) {
  95.         fclose(outf);
  96.         fprintf(stderr, "mcompress: will not overwrite \"%s\"\n", buf);
  97.         return 1;
  98.       }
  99.       argv[1] = buf;
  100.       argc++;
  101.     }
  102.   }
  103.   if (argc > 1 && strcmp("-", argv[1])) {
  104.     if (!(outf = fopen(argv[1], "w"))) {
  105.       fprintf(stderr, "mcompress: can't open \"%s\" for writing\n", argv[1]);
  106.       return 1;
  107.     }
  108.   }
  109.   if (decomp) {
  110.     if (header) {
  111.       if (getc(inf) != 037 || getc(inf) != 0235 || (n = getc(inf)) == EOF) {
  112.         fprintf(stderr, "mcompress: That's not a compressed file!\n");
  113.         return 1;
  114.       }
  115.       nbits = n & 0x1F;
  116.       block_compress = n & 0x80;
  117.     }
  118.     if (!(cstream = uncompinit(n & 0x1F, n & 0x80, stdread, inf))) {
  119.       fprintf(stderr, "mcompress: not enough memory\n");
  120.       return 1;
  121.     }
  122.     while ((n=uncompread(cstream, sizeof(buf),  buf)) > 0) {
  123. #ifdef    macintosh
  124.         SpinCursor(1);
  125.         if (unix) {
  126.             /* convert LF->CRs */
  127.             for (i = 0; i < sizeof(buf); i++)
  128.                 if ( *(buf + i) == '\r' )
  129.                     *(buf + i) = '\n';
  130.         }
  131.         fwrite(buf, 1, n, outf);
  132.     }
  133. #endif    macintosh
  134.     uncompclose(cstream);
  135. #ifdef    macintosh
  136.     if (unix && outf != stdout ) {
  137.         FInfo    fInfoRec;
  138.         
  139.         c2pstr (argv[1]);
  140.         (void) GetFInfo ((StringPtr) argv[1], 0, &fInfoRec);
  141.         fInfoRec.fdType = 'TEXT';
  142.         fInfoRec.fdCreator = 'MPS ';
  143.         (void) SetFInfo ((StringPtr)argv[1], 0, &fInfoRec);
  144.     }
  145. #endif    macintosh
  146.   }
  147.   else {
  148.     if (header) {
  149.       buf[0] = 037;
  150.       buf[1] = 0235;
  151.       buf[2] = nbits;
  152.       if (block_compress) buf[2] |= 0x80;
  153.       stdwrite(outf, 3, buf);
  154.     }
  155.     if (!(cstream = compinit(nbits, block_compress, stdwrite, outf))) {
  156.       fprintf(stderr, "mcompress: not enough memory\n");
  157.       return 1;
  158.     }
  159.     while ((n=fread(buf, 1, sizeof(buf), inf)) > 0) {
  160. #ifdef    macintosh
  161.         SpinCursor(1);
  162.         if (unix) {
  163.             /* convert CR->LFs */
  164.             for (i = 0; i < sizeof(buf); i++)
  165.                 if ( *(buf + i) == '\n' )
  166.                     *(buf + i) = '\r';
  167.         }
  168.         compwrite(cstream, n, buf);
  169.     }
  170. #endif    macintosh
  171.     compclose(cstream);
  172.   }
  173.   fflush(outf);
  174.   if (ferror(inf) || ferror(outf)) {
  175.     fprintf(stderr, "mcompress: I/O error\n");
  176.     return 2;
  177.   }
  178.   if (inf != stdin) fclose(inf);
  179.   if (outf != stdout) fclose(outf);
  180.   return 0;
  181.  
  182. badarg:
  183.   fprintf(stderr, "mcompress v1.0, by gz@entity.com.  Usage:\n\
  184. mcompress [-dCnH] [-b maxbits] [inputfile [outputfile]]\n\
  185.   -d         = Do decompression rather than compression.\n\
  186.   -b maxbits = max number of bits/code.  Must be between 9 and 16.\n\
  187.                 The default is 16.  Smaller values give worse results but require\n\
  188.                 less memory at runtime.\n\
  189.                 This option cannot be given for decompression unless -n is also specified.\n\
  190.   -C         = Do not perform 'block compression' (use only for compatibility with\n");
  191.    fprintf(stderr, "\
  192.                 obsolete versions of unix compress).\n\
  193.   -n         = Do not create/expect compress file header (for obsolete compatibility)\n\
  194.                 If this option is specified for decompression, -b must also be given.\n\
  195.   -u         = Convert CR/LFs to/from Unix text files\n");
  196.    fprintf(stderr, "\
  197.   -H         = show this help message\n\n\
  198.   If no files are specified, reads standard input and writes standard output.\n\n\
  199.   If inputfile is specified but no outputfile, the output defaults as follows:\n\
  200.     for compress:   the input filename with \".Z\" appended.\n\
  201.     for decompress: standard output.\n\
  202.   Only the data fork of the input file is processed.\n\n");
  203.    fprintf(stderr, "\
  204.   Note that unlike the unix version, the input file is NOT deleted.\n\n\
  205.   This is freeware.  If you paid money for this program, you got ripped off.\n");
  206.   return 2;
  207. }
  208.  
  209.